/*接收文件/文件夹线程的回调函数*/
#include 	"ipmsg.h"
#include 	"MyIpmsg.h"

/*-------------------------------------------------------------------------*/
void * getfiles(void * arg)
{
	char 			buf[1449] = {'\0'};
	char 			* t = NULL;
	char 			* t2 = NULL;
	char  			temp[65536] = {'\0'};
	FILE 			* fp;
	int 			numbytes;
	unsigned long long 	offset = 0;
	time_t 			now;
	unsigned int 		last_time;
	int 			len;
	struct utimbuf 		timebuf;
	transfolderheader 	folder;
	char 			buf_path[PATH_MAX];
	unsigned int 		header_len;
	unsigned long long 	buf_size;
	int 			buf_fileattr;
	time_t 			buf_mtime;
	time_t 			buf_ctime;
	char 			flag = 0;
	char 			fpflag = 0;
	char 			pocketEOFflag = 0;
	char 			* pointer = NULL;
	int 			depth = 0;
	int 			step;
	char 			* buf_offset = NULL;
	char 			YesNo[3];
	
	memset(folder.filename, 0, PATH_MAX);
	
	if( (trans_file_socs[0] = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		fprintf(stderr, "Socket error:%s\n\a", strerror(errno)); 
		exit(1); 
	}
	
	if(connect(trans_file_socs[0], (struct sockaddr *) ( &trans_file_from[0]), sizeof(struct sockaddr)) == -1) { 
		fprintf(stderr, "Connect Error:%s\a\n", strerror(errno)); 
		exit(1); 
	}
	
	now = time(NULL);
	last_time = 0;
	memset(buffer, 0, MAXSOCKBUF);
	if ( (unsigned int) now <= last_time)	
		now = ++last_time;
	last_time = now;
	
	if (files[filenum - 1].fileattr == 1)
		sprintf(buffer, "1:%u:%s:%s:%lu:%x:%x:%x:", \
				(unsigned int ) now, user, hostname, IPMSG_GETFILEDATA, \
				( (ipmsgdata *) arg)->packetno, (unsigned int ) (files[filenum-1].fileID), \
				(unsigned int ) offset);
	else if (files[filenum - 1].fileattr == 2)
		sprintf(buffer,"1:%u:%s:%s:%lu:%x:%x:", \
				(unsigned int ) now, user, hostname, IPMSG_GETDIRFILES, \
				( (ipmsgdata * ) arg)->packetno, files[filenum-1].fileID);
	
	len = strlen(buffer) + 1;
	send(trans_file_socs[0], buffer, len, 0);
	
	if (files[filenum-1].fileattr == IPMSG_FILE_REGULAR) {
		
		depth = 0;
		
		while (1) {
			if (access(files[filenum-1].filename, 0) == 0){
				
				printf("The filename already exsits.Do you want to replace it?[Y/N]\n");
				
				while (1){
					
					fgets(YesNo, 3, stdin);
					
					if (YesNo[0] != 'Y' && YesNo[0] != 'y' \
							&& YesNo[0] != 'N' && YesNo[0] != 'n') {
						printf("Please input Y(y) or N(n)\n");
						continue;
					}
					else if (YesNo[1] != '\n') {
						printf("Please input Y(y) or N(n)\n");
						continue;
					}
					
					YesNo[1] = '\0';
					
					break;
				}
				
				if(!strcmp(YesNo, "N") || !strcmp(YesNo, "n")) {
					printf("Please input the filename:\n");
					fgets(files[filenum-1].filename, PATH_MAX, stdin);
					files[filenum - 1].filename[strlen(files[filenum - 1].filename) - 1] = '\0';
				}
			}
			else
				break;
		}
		
		if ( (fp = fopen(files[filenum - 1].filename, "wb")) == NULL) {
			perror("fopen error");
			exit(1);
		}
		
		offset = 0;
		
		while (1){
			
			if ( (numbytes = recv(trans_file_socs[0], buf, 1448, 0)) == -1){		
				perror("recv error");
				exit(1);
			}
			
			offset += numbytes;
			fwrite(buf, 1, numbytes, fp);
			
			if(offset == files[filenum - 1].size)
				break;
		}
		
		fclose(fp);
		timebuf.modtime = (time_t ) files[filenum - 1].mtime;
		if(utime(files[filenum - 1].filename, & timebuf) == -1) {
			perror("utime");
			exit(1);
		}
		
	}
	else if (files[filenum - 1].fileattr == IPMSG_FILE_DIR){
		//此处写创建目录并接收文件夹的代码
		depth++;
		offset = 0;
		step = 1;
		
		while (1) {
			if (!pocketEOFflag) {
				if( (numbytes = recv(trans_file_socs[0], buf, 1448, 0)) == -1) {
					perror("recv error");
					exit(1);
				}
				
				pocketEOFflag = 1;
				pointer = buf;
			}
			
			if (!flag) {
				flag = 1;
				step = strlen(temp);
				strcat(temp, pointer);
				
				if (strlen(temp) < 4) {
					pocketEOFflag = 0;
					flag = 0;
					continue;
				}
				else
					sscanf(temp, "%x", & header_len);
				
				if (strlen(temp) < header_len) {
					pocketEOFflag = 0;
					flag = 0;
					continue;
				}
				
				buf_offset = pointer + abs(header_len - step);
				t = strchr(temp, ':');
				t2 = strchr(t + 1, ':');
				if (t2 == t +1)
					memmove(t2, t2 + 1, strlen(t2 + 1));
				
				strncpy(buf_path, t + 1, t2 - t - 1);
				sscanf(t2+1, "%llx", & buf_size);
				t2 = strchr(t2 + 1, ':');
				sscanf(t2 + 1, "%x", & buf_fileattr);
				t2 = strchr(t2 + 1, ':');
				sscanf(t2 + 1, "%x", & len);
				
				if (len == IPMSG_FILE_MTIME) {
					t2 = strchr(t2 + 1, '=');
					sscanf(t2 + 1, "%lx", & buf_mtime);
				}
				
				t2 = strchr(t2 + 1, ':');
				sscanf(t2 + 1, "%x", & len);
				pointer = buf_offset;
				
				if (len == IPMSG_FILE_CREATETIME) {
					t2 = strchr(t2 + 1, '=');
					sscanf(t2 + 1, "%lx", & buf_ctime);
				}
				
				offset = 0;
				memset(temp, 0, 1449);
			}
			
			if ( (pointer - buf) == numbytes) {
				pocketEOFflag = 0;
				pointer = buf;
				if (buf_fileattr != IPMSG_FILE_RETPARENT)
					continue;
			}
			
			if (buf_fileattr == IPMSG_FILE_REGULAR) {	/*接收到的是文件夹中的文件*/
				if (!fpflag) {
					folder.headersize = header_len;
					strcat(folder.filename, buf_path);
					folder.filesize = buf_size;
					folder.fileattr = buf_fileattr;
					folder.filemtime = buf_mtime;
					folder.filectime = buf_ctime;
					
					printf("%s\n", folder.filename);
					
					if( (fp = fopen(folder.filename, "wb")) == NULL) {
						printf("flag = %d\n", flag);
						perror("fopen");
						exit(1);
					}
					fpflag = 1;
				}
				
				if ( (numbytes - (pointer - buf)) >= (folder.filesize - offset)) {	/*如果在接收的一个包中剩余字节数大于文件的长度*/
					fwrite(pointer, 1, (folder.filesize - offset), fp);
					pointer += folder.filesize - offset;
					flag = 0;
					fclose(fp);
					header_len = 0;
					fpflag = 0;
					t = strrchr(folder.filename, '/');
					t += 1;
					* t = '\0';
					memset(t, 0, strlen(buf_path));
					memset(buf_path, 0, strlen(buf_path));
					offset += folder.filesize - offset;
				}
				else {
					fwrite(pointer, 1, numbytes - (pointer - buf), fp);
					offset += numbytes - (pointer - buf);
					pointer += numbytes - (pointer - buf);
				}
			}
			else if (buf_fileattr == IPMSG_FILE_DIR) {	/*接收到的是文件夹中的文件夹*/
				folder.headersize = header_len;
				strcat(folder.filename, buf_path);
				strcat(folder.filename, "/");
				folder.filesize = buf_size;
				folder.fileattr = buf_fileattr;
				folder.filemtime = buf_mtime;
				folder.filectime = buf_ctime;
				
				printf("%s\n", folder.filename);
				
				if( mkdir(folder.filename, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH |S_IXOTH) == -1) {
					perror("mkdir");
					exit(1);
				}
				
				depth++;
				flag = 0;
				memset(buf_path, 0, strlen(buf_path));
				header_len = 0;
			}
			else if (buf_fileattr == IPMSG_FILE_RETPARENT) {	/*文件夹结束*/
				
				depth--;
				
				if (depth == 1)
					break;
				t = strrchr(folder.filename, '/');
				* t = '\0';
				t2 = strrchr(folder.filename, '/');
				memset(t2 + 1, 0, t - t2);
				flag = 0;
				header_len = 0;
			}
			if ( (pointer - buf) == numbytes) {
				pocketEOFflag = 0;
				pointer = buf;
			}
		}
	}
	close(trans_file_socs[0]);
	return NULL;
}
